
// // // 1. 实现连缀调用  ====》 每一个方法内部都需要返回实例
// // // Person('people').eat('banner').sleep(3000).eat('apple').sleepFirst(4000).eat('梨')
// // // 以此调用为例最终的结果为：打印台先等待4S（sleepFirst的作用）,然后打印this is people，然后打印‘吃香蕉’，然后等待3S（sleep的作用），再打印‘吃apple’，最后打印‘吃梨’
// // // 只要在链式中出现sleepFirst那就得先执行它--> 让整个执行程序先‘沉睡’

// let stack = []; //事件队列  [function(){},function(){}，。。。]

// let index = 0;  //下标

// function next(){
//     let fn = stack[index]; //取到当前的函数
//     index++;
//     if(typeof fn === 'function'){
//         fn();
//     }
// }
// class Person{
//     // your codes
//     constructor(name){
//         console.log(name)
//         stack.push(function(){
//             console.log('this is people');
//             next();
//         })
//     }

//     eat(food){
//         //console.log('吃',food)
//         stack.push((function(){
//             console.log('吃',food);
//             next();
//         }))
//         return this
//     }

//     sleep(time){
//         //超时  setTimeout 3000 console.log('sleep的作用')
//         stack.push(function(){
//             setTimeout(() => {
//                 console.log('sleep的作用');
//                 next();
//             },time)
//         })
//         return this
//     }

//     sleepFirst(time){
//         //超时  setTimeout 4000
//         stack.unshift(function(){
//             setTimeout(() => {
//                 console.log('sleepFirst的作用');
//                 next();
//             },time)
//         })
//         return this
//     }
// }

// new Person('people').eat('banner').sleep(3000).eat('apple').sleepFirst(4000).eat('梨')
// next();

//ES5

// function Man(name,age){
//     this.name = name;
//     this.age = age;
// }

// Man.prototype.say = function(){
//     console.log("说话")
// }

// new Man('zs',19);

// Man('lisi',10);

// // 2. 补全代码 generator函数
function getNumber(timer) {
    // 在time时间之后生成一个1-100之间的随机数，并返回
    return new Promise((resolve,reject) => {
        setTimeout(() => {
            let num = Math.ceil(Math.random()*100); //0-100
            resolve(num);
        },timer)
    })    
}

//getNumber的返回值 promise对象

//

let arr = [1,2,3];

console.log(arr.keys());

//1.for of 

//2.next()

// for(let key of arr.keys()){
//     console.log(key)
// }

// let inter = arr.keys();

// console.log(inter.next());
// console.log(inter.next());
// console.log(inter.next());
// console.log(inter.next()); //{value:'',done:}

/**
 * dva
 * 
 * generator函数是一个状态机，内部封装了很多状态。
 * 
 * generator两个特征：1.function关键字与函数名之间有一个星号；  2.函数体内部使用yield表达式，定义不同的内部状态
 * 
 * generator的返回值是遍历器对象,next() for of
 * 
 * yield 表达式没有返回值，next()可以传递一个参数，作为上一个yield表达式的返回值
 * 
 * generator可以控制函数内部状态的执行顺序
 *
*/

function* reducerNumber() {
    const number_1 = yield getNumber(300);
    const number_2 = yield getNumber(300); 
    const number_3 = yield getNumber(300); 
    const number_4 = yield getNumber(300);
    return number_4
}

const o = reducerNumber(); //遍历器对象

// console.log(o.next()) ;//{value:promise对象,done:false:}

// console.log(o.next(1)) ;//

// console.log(o.next(2)) ;//

function run(gen) {
    return new Promise((resolve,reject) => {
        let total = 0; //总数
        let next = (num) => {
            let result = gen.next(num);
            if(result.done){
                console.log("====",result.value)
                resolve(result.value)
                return false
            }
            result.value.then(num => {
                console.log(num)
                total += num;
                next(total);
            })
        }
        next(0)
    })
    
};

// // 该方法最终返回number_1 -- number_4的和
run(o).then(total =>{
    console.log(total)
})

/**
 * async ES7  generator
 * 
 * async不能控制函数内部状态的执行
 * 
 * generator控制函数内部状态的执行
 * 
*/

async function fun(){
    await 'hello'
    await 'world'
    await 'end'
}

fun();